package com.tsq.security.auth.base;

import com.tsq.admin.api.model.SysUserInfo;
import com.tsq.security.auth.model.AuthUser;
import com.tsq.security.auth.service.UserServiceDetailImpl;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.provider.*;
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 无密码授权+直接注册
 *
 * @author Tango
 * @since 2020/9/7
 */
public abstract class PasswordFreeGranter extends AbstractTokenGranter{


    protected PasswordFreeGranter(AuthorizationServerTokenServices tokenServices,
                                  ClientDetailsService clientDetailsService,
                                  OAuth2RequestFactory requestFactory, String grantType) {
        super(tokenServices, clientDetailsService, requestFactory, grantType);
    }



    /**
     * 验证逻辑
     *
     * @param parameters 请求参数
     * @return Authentication
     */
    protected abstract Authentication parameterGrant(Map<String, String> parameters);


    /**
     * @return UserDetailsService
     */
    protected abstract UserServiceDetailImpl getUserDetailsServiceBean();


    @Override
    protected final OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
        Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
        Authentication auth = parameterGrant(parameters);
        OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
        return new OAuth2Authentication(storedOAuth2Request, auth);
    }

    //验证失败
    protected final <T> T fail(String msg){
        throw new InvalidGrantException(msg);
    }


    //查库
    protected UserDetails getUser(String username){
        UserDetails userDetails = getUserDetailsServiceBean().loadUserByUsername(username);
        if(userDetails == null){
            userDetails = makeUser(username);
        }
        return userDetails;
    }

    //注册
    private UserDetails makeUser(String username){
        //TODO 用户其他信息补全
        SysUserInfo sysUserInfo = new SysUserInfo();
        sysUserInfo.setUsername(username);

        if(getUserDetailsServiceBean().save(sysUserInfo)){
            AuthUser authUser = new AuthUser();
            authUser.setSysUserInfo(sysUserInfo);
            return authUser;
        }
        return fail("验证错误: 注册失败: " + username);
    }



}
